package com.hfzy.ihk.web.linkcall.biz;

import com.google.common.collect.Lists;
import com.hfzy.ihk.common.core.elasticsearch.EsQueryUtils;
import com.hfzy.ihk.common.core.elasticsearch.service.EsBaseServiceImpl;
import com.hfzy.ihk.common.util.Utils;
import com.hfzy.ihk.common.util.string.StringUtil;
import com.hfzy.ihk.common.util.uuid.base64uuid.UUIDs;
import com.hfzy.ihk.common.web.WebResult;
import com.hfzy.ihk.facade.linkcall.entity.BusinessTypeBase;
import com.hfzy.ihk.facade.linkcall.entity.flow.config.SpeakingFlow;
import com.hfzy.ihk.facade.linkcall.entity.knowledge.type.IndustryType;
import com.hfzy.ihk.web.linkcall.biz.KnowledgeBase.type.IndustryTypeBiz;
import com.hfzy.ihk.web.linkcall.dao.BusinessTypeBaseRepository;
import com.hfzy.ihk.web.linkcall.support.annotation.PreProcessParam;
import com.hfzy.ihk.web.linkcall.utils.UserUtils;
import com.hfzy.ihk.web.linkcall.utils.WebResultUtils;
import org.apache.tomcat.util.buf.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class BusinessTypeBaseBiz extends EsBaseServiceImpl<BusinessTypeBase> {

    @Autowired
    BusinessTypeBaseRepository businessTypeBaseRepository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Autowired
    IndustryTypeBiz industryTypeBiz;

    @Override
    protected ElasticsearchCrudRepository getReposity() {
        return businessTypeBaseRepository;
    }

    public WebResult save(BusinessTypeBase businessTypeBase){
        WebResult webResult = null;
        try {
            Long currentUserId = UserUtils.getCurrentUserId()!=null?UserUtils.getCurrentUserId():0l;
            if(businessTypeBase.getId()==null || Utils.isNullString(businessTypeBase.getId()) || "null".equals(businessTypeBase.getId())){
                businessTypeBase.setId(UUIDs.base64UUID());
                businessTypeBase.setCreateUserId(currentUserId);
                businessTypeBase.setModTime(new Date());
                businessTypeBase.setCreateTime(new Date());
                businessTypeBase.setModUserId(currentUserId);
            }else{
                businessTypeBase.setModUserId(currentUserId);
                businessTypeBase.setModTime(new Date());
            }
            Map map = new HashMap();
            map.put("name",businessTypeBase.getName());
            List<BusinessTypeBase> businessTypeBaseList = getBusinessTypeBaseList(map);
            if(businessTypeBaseList!=null && !businessTypeBaseList.isEmpty()){
                if(!businessTypeBaseList.stream().map(it->it.getId()).collect(Collectors.toList()).contains(businessTypeBase.getId())){
                    webResult = WebResultUtils.getFailCharWebResult("该类型已经存在了！");
                    return webResult;
                }
            }
            businessTypeBaseRepository.save(businessTypeBase);
            webResult = WebResultUtils.getSuccessCharWebResult("",0,null);
        }catch (Exception e){
            webResult = WebResultUtils.getExceptionCharWebResult("操作异常 "+e.getMessage());
        }finally {
            if(webResult==null)
                webResult = WebResultUtils.getFailCharWebResult("");
        }
        return webResult;
    }


    public List<BusinessTypeBase> getAll(){
        Iterable<BusinessTypeBase> businessTypeBases = businessTypeBaseRepository.findAll();
        List<BusinessTypeBase> bList = Lists.newArrayList(businessTypeBases);
        return bList;
    }

    @PreProcessParam
    public List<BusinessTypeBase> getBusinessTypeBaseList(Map<String,String> params){
        /*BoolQueryBuilder boolQueryBuilder = getQueryBuilderByParams(params);
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .build();
        return elasticsearchTemplate.queryForList(searchQuery,BusinessTypeBase.class);*/
        List<BusinessTypeBase> businessTypeBases = null;
        BoolQueryBuilder boolQueryBuilder = getQueryBuilderByParams(params);
        Iterator<BusinessTypeBase> iterator = businessTypeBaseRepository.search(boolQueryBuilder).iterator();
        if (iterator != null) {
            businessTypeBases = new ArrayList<BusinessTypeBase>();
            while (iterator.hasNext()) {
                BusinessTypeBase next = iterator.next();
                businessTypeBases.add(next);
            }
        }
        return businessTypeBases;
    }

    public Page<BusinessTypeBase> getPageByCondition(int pageNum, int pageSize, BoolQueryBuilder boolQueryBuilder, FieldSortBuilder fieldSortBuilder){
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder).withSort(fieldSortBuilder).withPageable(PageRequest.of(pageNum,pageSize));
        return businessTypeBaseRepository.search(builder.build());
    }

    @PreProcessParam
    public Page<BusinessTypeBase> getByPage(Map<String,String> params){
        BoolQueryBuilder boolQueryBuilder = getQueryBuilderByParams(params);
        int pageNum = Integer.valueOf(params.get("page"))-1;
        int pageSize = Integer.valueOf(params.get("pageSize"));
        //添加排序字段
        FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("createTime").order(SortOrder.DESC);
        return getPageByCondition(pageNum,pageSize,boolQueryBuilder,fieldSortBuilder);
    }



    public BoolQueryBuilder getQueryBuilderByParams(Map<String,String> params){
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        Iterator entries = params.entrySet().iterator();
        while (entries.hasNext()){
            Map.Entry entry = (Map.Entry) entries.next();
            String key = entry.getKey().toString();
            switch (key){
                case "createUserId":
                    QueryBuilder queryBuilder = EsQueryUtils.termQuery("createUserId",params.get("createUserId"));
                    boolQueryBuilder.must(queryBuilder);
                    break;
                case "id":
                    boolQueryBuilder.must(EsQueryUtils.termQuery("id",params.get("id")));
                    break;
                case "parentId":
                    boolQueryBuilder.must(EsQueryUtils.termQuery("parentId",params.get("parentId")));
                    break;
                case "ids":
                    boolQueryBuilder.must(EsQueryUtils.termsQuery("id",params.get("ids").split(",")));
                    break;
                case "createTimeStart"://格式：yyyy-MM-dd HH:mm:ss
                    boolQueryBuilder.must(EsQueryUtils.rangeQuery("createTime", params.get("createTimeStart"),
                            null, true, false));
                    break;
                case "createTimeEnd":
                    boolQueryBuilder.must(EsQueryUtils.rangeQuery("createTime", null,
                            params.get("createTimeEnd"), false, true));
                    break;
                case "name":
                    EsQueryUtils.boolQuery(boolQueryBuilder, EsQueryUtils.BoolType.MUST, EsQueryUtils.wildcardQuery("name", "*"+params.get("name")+"*"));
                    break;
                default:
                    break;
            }
        }
        return boolQueryBuilder;
    }

    public WebResult deleteBusinessTypeBaseById(String id){
        WebResult webResult = null;
        try{
            //todo ===> 根据该id 找到 此分支下的子类
            //先判断有没有被引用，如果被引用则提示不给删除
            Map param = new HashMap();
            param.put("businessTypeBaseId",id);
            List<IndustryType> industryTypes = industryTypeBiz.getIndustryTypesList(param);
            if(industryTypes!=null && !industryTypes.isEmpty()){
                List<String> names = industryTypes.stream().map(it->it.getName()).collect(Collectors.toList());
//                throw  new Exception("该业务类型已经被使用在行业类型中，如:"+ StringUtils.join(names,','));
                return    WebResultUtils.getFailCharWebResult("删除失败，该业务类型已经被使用在行业类型中，如:"+ StringUtils.join(names,','));
            }
            boolean flag = deleteById(id);
            if(flag){
                webResult = WebResultUtils.getSuccessCharWebResult("",0,null);
            }
        }catch (Exception e){
            webResult = WebResultUtils.getExceptionCharWebResult("");
        }finally {
            if(webResult==null)
                webResult = WebResultUtils.getFailCharWebResult("参数异常");
        }
        return  webResult;
    }


}
